package com.tianyu.inspection.common.model;

import org.springframework.ui.ModelMap;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author swyan
 */

public class MapModel {
	/**
	 * 实体类转Map对象
	 * @param entity 实体类
	 * @return 实体类转化为的Map对象
	 */
	public static Map<String,Object> entityToMap(Object entity){
		if (Objects.isNull(entity)){
			return null;
		}
		Map<String, Object> entityMap = new HashMap<>(15);
		Field[] declaredFields = entity.getClass().getDeclaredFields();
		for (Field item : declaredFields){
			item.setAccessible(true);
			try {
				if (Objects.nonNull(item.get(entity))){
					entityMap.put(item.getName(),item.get(entity));
				}
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return entityMap;
	}
	/**
	 * 实体类转Map对象
	 * @param entity 实体类
	 * @return 实体类转化为的Map对象
	 */
	public static Map<String,Object> entityToLineKeyMap(Object entity){
		if (Objects.isNull(entity)){
			return null;
		}
		Map<String, Object> entityMap = new HashMap<>(15);
		Field[] declaredFields = entity.getClass().getDeclaredFields();
		for (Field item : declaredFields){
			item.setAccessible(true);
			try {
				if (Objects.nonNull(item.get(entity))){
					entityMap.put(humpToLine(item.getName()),item.get(entity));
				}
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return entityMap;
	}

	/**
	 * 字符串转Map对象
	 * @param string 字符串
	 * @return Map对象
	 */
	public static HashMap<String,Object> stringToMap(String string){
		HashMap<String, Object> map = new HashMap<>(10);
		String emptyString = "{}";
		if (emptyString.equals(string)){
			return map;
		}
		boolean isJsonString = string.startsWith("\"") && string.endsWith("\"");
		if (isJsonString){
			map.put("error","非法字符串");
			return map;
		}
		string = string.substring(1, string.length() - 1);
		String[] keyValues = string.split(",");
		for (String item : keyValues){
			String[] split = item.split(":");
			String key = split[0];
			String value = split[1];
			boolean keyFlag = key.startsWith("\"") && key.endsWith("\"");
			if (keyFlag) {
				key = key.substring(1,key.length()-1);
			}
			boolean valueFlag = value.startsWith("\"") && value.endsWith("\"");
			if (valueFlag) {
				value = value.substring(1,value.length()-1);
				map.put(key,value);
			} else {
				if ("null".equals(value)){
					map.put(key,null);
				} else if ("true".equals(value) || "false".equals(value)){
					boolean b = Boolean.parseBoolean(value);
					map.put(key,b);
				} else {
					Number number = Long.parseLong(value);
					map.put(key,number);
				}
			}
		}
		return map;
	}

	public static Pattern patternLineToHump = Pattern.compile("_(\\w)");
	public static Pattern patternHumpToLine = Pattern.compile("[A-Z]");
	public static ModelMap getLineKeyMap(Map<String,Object> map){
		ModelMap modelMap = new ModelMap();
		if (Objects.nonNull(map)){
			Set<String> strings = map.keySet();
			strings.forEach(key-> modelMap.addAttribute(humpToLine(key),map.get(key)));
		}
		return modelMap;
	}

	public static ModelMap getHumpKeyMap(HashMap<String,Object> map){
		ModelMap modelMap = new ModelMap();
		Set<String> strings = map.keySet();
		strings.forEach(key->{
			modelMap.addAttribute(lineToHump(key),map.get(key));
		});
		return modelMap;
	}

	public static String lineToHump(String str) {
		Matcher matcher =  patternLineToHump.matcher(str.toLowerCase());
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
		}
		matcher.appendTail(sb);
		return sb.toString();
	}

	public static String humpToLine(String str) {
		Matcher matcher = patternHumpToLine.matcher(str);
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
		}
		matcher.appendTail(sb);
		return sb.toString();
	}

	public static Boolean isFieldExist(Class<?> clazz,String ...columns){
		for (String column : columns){
			try {
				boolean result = clazz.getDeclaredField(column).getName().equals(column);
				if (!result){
					return false;
				}
			} catch (NoSuchFieldException e) {
				return false;
			}
		}
		return true;
	}
}